﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.IO;
using System.IO.IsolatedStorage;
using System.Collections;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Services;
using MainGame.SaveData;
using MainGame.GamePlay;
using System.Diagnostics;
using MainGame.GameSound;

namespace MainGame.Menu
{ 
  public interface ISettings { }

  public class GameSettingsMenu : BaseMenu, ISettings
  {
    SpriteBatch spriteBatch;

    // Graphics
    private Button ChangeBg, SelectedBg, ChangeDeck, SelectedDeck, SelectedBDeck, square;
    private Color color;
    public bool Animated = false, backClicked = false, SquareOn = false;
    public int Direction = 1, alphaChange = 1, AnimVelocity = 160;
    private Backgrounds currentBackground;
    private Decks currentDeck;

    // Audio
    private Button[] volumeBars, volumeBtn;
    private Button soundFX;
    public bool onClick = false, menuSwitched = false;
    public int Vol = 0, timer = 7, pressedBtn, grow = 1, direction = 1;
    private int VOLUMEBARS_NUM = 5;
    private Color colorDisplayString = new Color(230, 0, 0);
    private Texture2D soundOnTexture, soundOffTexture, back;
    private SpriteFont baveuse;

    public GameSettingsMenu(Game game, MenuDepths depth)
      : base(game, depth)
    {
      background = null;
      back = game.Content.Load<Texture2D>(@"Images//Menu//HelpBg2");
      bounds = new Rectangle(50, 30, 700, 380);
    }

    protected override void Dispose(bool disposing)
    {
      base.Dispose(disposing);
    }

    public override void Initialize()
    {
      // GRAPHICS
      color = Color.Yellow;
      color.R = 150;

      spriteBatch = Game.GetContext().SpriteBatch;

      //load saved graphics configuration

      //load saved background configuration
      currentBackground = Game.GetContext().currentConfig.chosenBackground;
     
      //load saved deck configuration
      currentDeck = Game.GetContext().currentConfig.chosenDeck;
      
      // Load all buttons
      square = new Button(Game, @"Images//Menu//square", new Rectangle(0, 40, 160, 160), Color.Transparent, "small_font", "", Color.Blue);
      AddButton(square, () =>
      {});

      ChangeBg = new Button(Game, @"Images//Menu//button2", new Rectangle(90, 250, 140, 100), Color.Green, "baveuse1_font", Locale.Strings.ChangeBackground.Replace("\\n", "\n"), new Color(29, 214, 255), 0.8f);
      AddButton(ChangeBg, () =>
      {
        ChangeBg.touched = true;

        changeBackground();
        
        SquareOn = true;
        square.bounds.X = SelectedBg.bounds.X - 10;
        square.bounds.Y = SelectedBg.bounds.Y - 10;
        square.bounds.Width = SelectedBg.bounds.Width + 20;
        square.bounds.Height = SelectedBg.bounds.Height + 20;

        Game.GetContext().currentConfig.chosenBackground = currentBackground;
        
      });

      SelectedBg = new Button(Game, @"Images//Backgrounds//Thumbs//Bg_" + currentBackground.ToString(), new Rectangle(90, 80, 140, 140), Color.White, "small_font", "", Color.Blue);
      AddButton(SelectedBg, () => { });

      ChangeDeck = new Button(Game, @"Images//Menu//button2", new Rectangle(290, 250, 140, 100), Color.Green, "baveuse1_font", Locale.Strings.ChangeDeck.Replace("\\n", "\n"), new Color(29, 214, 255), 0.8f);
      AddButton(ChangeDeck, () =>
      {
        ChangeDeck.touched = true;

        changeDeck();
        SquareOn = true;
        square.bounds.X = SelectedDeck.bounds.X - 10;
        square.bounds.Y = SelectedDeck.bounds.Y - 10;
        square.bounds.Width = SelectedDeck.bounds.Width + 20;
        square.bounds.Height = SelectedDeck.bounds.Height + 20;

        Game.GetContext().currentConfig.chosenDeck = currentDeck;
      });

      SelectedDeck = new Button(Game, @"Images//Decks//Deck_" + currentDeck.ToString() + "_mini", new Rectangle(290, 100, 145, 90), Color.White, "small_font", "", Color.Blue);
      AddButton(SelectedDeck, () => { });

      // AUDIO

      volumeBars = new Button[VOLUMEBARS_NUM];
      volumeBtn = new Button[2];

      int volBarDist = 20;
      int numBarsToColor;

      soundOnTexture = Game.Content.Load<Texture2D>(@"Images//Menu//SoundON");
      soundOffTexture = Game.Content.Load<Texture2D>(@"Images//Menu//SoundOFF");

      baveuse = Game.Content.Load<SpriteFont>("baveuse1_font");

      for (int i = 0; i < VOLUMEBARS_NUM; i++)
      {
        var curr_i = i;

        volumeBars[i] = new Button(Game, @"white_pixel", new Rectangle(520 + ((i + 1) * 25), 150 - volBarDist, 15, volBarDist), Color.White, "small_font", "", Color.Yellow);
        AddButton(volumeBars[i], () =>
        {

        });

        volBarDist += 10;
      }

      for (int i = 0; i < 2; i++)
      {
        var curr_i = i;

        volumeBtn[i] = new Button(Game, @"Images//Menu//setVol" + i, new Rectangle(470 + (i * 210), 120, 50, 50), Color.PaleTurquoise, "small_font", "", Color.Yellow);
        AddButton(volumeBtn[i], () =>
        {
          // Color the volume bars when volume up/down buttons are pressed
          float volumeStep = 1.0f / VOLUMEBARS_NUM;
          int currentVolume = (int)(Game.GetContext().currentConfig.sfxVolume * VOLUMEBARS_NUM);
          if (curr_i == 0)
          {
            // Volume down pressed
            if (currentVolume > 1)
              Game.GetContext().currentConfig.sfxVolume -= volumeStep;
            else
              Game.GetContext().currentConfig.sfxVolume = 0f;
          }
          else
          {
            // Volume up pressed
            if (currentVolume < VOLUMEBARS_NUM - 1)
              Game.GetContext().currentConfig.sfxVolume += volumeStep;
            else
              Game.GetContext().currentConfig.sfxVolume = 1.0f;
          }

          numBarsToColor = (int)(Game.GetContext().currentConfig.sfxVolume * VOLUMEBARS_NUM);
          for (int x = 0; x < VOLUMEBARS_NUM; x++)
          {
            if (x < numBarsToColor)
              volumeBars[x].color = Color.Tomato;
            else
              volumeBars[x].color = Color.White;
          }

          var soundManager = Game.Services.GetService(typeof(ISoundManager<MenuSounds>)) as ISoundManager<MenuSounds>;
          soundManager.SfxVolume = Game.GetContext().currentConfig.sfxVolume;

          pressedBtn = curr_i;
          onClick = true;
        });
      }

      soundFX = new Button(Game, @"Images//menu//SoundOn", new Rectangle(550, 270, 60, 60), Color.White, "small_font", "", Color.Yellow);
      AddButton(soundFX, () =>
      {
        if (soundFX.texture.Equals(soundOnTexture))
        {
          soundFX.texture = soundOffTexture;
          Game.GetContext().currentConfig.sfxMuted = true;
        }
        else
        {
          soundFX.texture = soundOnTexture;
          Game.GetContext().currentConfig.sfxMuted = false;
        }

      });

      // Load the settings for the current profile
      numBarsToColor = (int)(Game.GetContext().currentConfig.sfxVolume * VOLUMEBARS_NUM);
      for (int x = 0; x < VOLUMEBARS_NUM; x++)
      {
        if (x < numBarsToColor)
          volumeBars[x].color = Color.Tomato;
        else
          volumeBars[x].color = Color.White;
      }


      if (!Game.GetContext().currentConfig.sfxMuted)
        soundFX.texture = soundOnTexture;
      else
        soundFX.texture = soundOffTexture;

      base.Initialize();
    }

    // Graphics

    private void changeBackground()
    {      
      if (currentBackground < Backgrounds.NumBackgrounds - 1)
        currentBackground++;
      else
        currentBackground = 0;
         
      SelectedBg.texture = Game.Content.Load<Texture2D>(@"Images//Backgrounds//Thumbs//Bg_" + currentBackground.ToString());         
    }

    private void changeDeck()
    {
      if (currentDeck < Decks.NumDecks - 1)
        currentDeck++;
      else
        currentDeck = 0;
      
      SelectedDeck.texture = Game.Content.Load<Texture2D>(@"Images//Decks//Deck_" + currentDeck.ToString() + "_mini");
    }


    public override void Update(GameTime gameTime)
    {
      // Graphics

      if (SquareOn)
      {
        color.R += (byte)(alphaChange * 10);

        if ((color.R >= 240) || (color.R <= 10))
          alphaChange *= -1;

        square.color = color; 
      }

      if (backClicked)
      {
        foreach (Button b in (from cb in buttons select cb.b))
        {
          b.bounds.X += AnimVelocity - 60;
        }
      }
      
      // Audio

      //Color the volume buttons when clicked
      if (onClick)
      {
        volumeBtn[pressedBtn].color = Color.SkyBlue;
        timer--;

        if (timer <= 0)
        {
          volumeBtn[pressedBtn].color = Color.Azure;
          onClick = false;
          timer = 10;
        }
      }

      // Enlarge the button Fx size
      if (grow < 50)
      {
        grow += 2;
        soundFX.bounds.Width += 2;
        soundFX.bounds.Height += 2;
      }
      
      base.Update(gameTime);
    }
    
    public override void Draw(GameTime gameTime)
    {
      spriteBatch.Begin();

      spriteBatch.Draw(back, new Rectangle(60, 30, 700, 370), new Color(0, 0, 0, 150));
      spriteBatch.Draw(back, new Rectangle(50, 30, 700, 360), new Color(29, 114, 192, 200));

      if (!backClicked)
      {
        spriteBatch.Draw(Game.Content.Load<Texture2D>(@"Images//Game//roundedBox"), new Rectangle(80, (int)bounds.Y + 40, 160, 160), new Color(40, 100, 10, 60));
        spriteBatch.Draw(Game.Content.Load<Texture2D>(@"Images//Game//roundedBox"), new Rectangle(280, (int)bounds.Y + 60, 165, 110), new Color(40, 100, 10, 60));

        spriteBatch.DrawString(baveuse, Locale.Strings.SoundVolume, new Vector2(450, 210), colorDisplayString);
      }

      spriteBatch.End();     

      base.Draw(gameTime);
    }

  }
}
